home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / RCS / envelope.c,v < prev    next >
Encoding:
Text File  |  1991-06-25  |  20.5 KB  |  1,007 lines

  1. head    5.22;
  2. branch    5.22.0;
  3. access;
  4. symbols
  5.     RELEASE:5.22.0.14
  6.     BETA:5.22.0.12
  7.     UICSO:5.22.0
  8.     VANILLA:5.22;
  9. locks; strict;
  10. comment    @ * @;
  11.  
  12.  
  13. 5.22
  14. date    90.06.20.08.35.46;    author paul;    state Exp;
  15. branches
  16.     5.22.0.1;
  17. next    ;
  18.  
  19. 5.22.0.1
  20. date    90.06.21.13.47.56;    author paul;    state Exp;
  21. branches;
  22. next    5.22.0.2;
  23.  
  24. 5.22.0.2
  25. date    90.07.09.10.18.41;    author paul;    state Exp;
  26. branches;
  27. next    5.22.0.3;
  28.  
  29. 5.22.0.3
  30. date    90.10.16.11.26.36;    author paul;    state Exp;
  31. branches;
  32. next    5.22.0.4;
  33.  
  34. 5.22.0.4
  35. date    90.11.13.14.33.17;    author paul;    state Exp;
  36. branches;
  37. next    5.22.0.5;
  38.  
  39. 5.22.0.5
  40. date    90.11.24.21.45.27;    author paul;    state Exp;
  41. branches;
  42. next    5.22.0.6;
  43.  
  44. 5.22.0.6
  45. date    91.01.19.19.26.02;    author paul;    state Exp;
  46. branches;
  47. next    5.22.0.7;
  48.  
  49. 5.22.0.7
  50. date    91.02.17.04.13.28;    author paul;    state Exp;
  51. branches;
  52. next    5.22.0.8;
  53.  
  54. 5.22.0.8
  55. date    91.03.04.21.48.23;    author paul;    state Exp;
  56. branches;
  57. next    5.22.0.9;
  58.  
  59. 5.22.0.9
  60. date    91.04.05.14.55.15;    author paul;    state Exp;
  61. branches;
  62. next    5.22.0.10;
  63.  
  64. 5.22.0.10
  65. date    91.05.18.17.27.51;    author paul;    state Exp;
  66. branches;
  67. next    5.22.0.11;
  68.  
  69. 5.22.0.11
  70. date    91.05.23.21.32.01;    author paul;    state Exp;
  71. branches;
  72. next    5.22.0.12;
  73.  
  74. 5.22.0.12
  75. date    91.05.29.19.43.33;    author paul;    state Exp;
  76. branches;
  77. next    5.22.0.13;
  78.  
  79. 5.22.0.13
  80. date    91.06.07.20.15.06;    author paul;    state Exp;
  81. branches;
  82. next    5.22.0.14;
  83.  
  84. 5.22.0.14
  85. date    91.06.21.12.47.26;    author paul;    state Exp;
  86. branches;
  87. next    ;
  88.  
  89.  
  90. desc
  91. @@
  92.  
  93.  
  94. 5.22
  95. log
  96. @5.64 Berkeley release
  97. @
  98. text
  99. @/*
  100.  * Copyright (c) 1983 Eric P. Allman
  101.  * Copyright (c) 1988 Regents of the University of California.
  102.  * All rights reserved.
  103.  *
  104.  * Redistribution and use in source and binary forms are permitted provided
  105.  * that: (1) source distributions retain this entire copyright notice and
  106.  * comment, and (2) distributions including binaries display the following
  107.  * acknowledgement:  ``This product includes software developed by the
  108.  * University of California, Berkeley and its contributors'' in the
  109.  * documentation or other materials provided with the distribution and in
  110.  * all advertising materials mentioning features or use of this software.
  111.  * Neither the name of the University nor the names of its contributors may
  112.  * be used to endorse or promote products derived from this software without
  113.  * specific prior written permission.
  114.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  115.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  116.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  117.  */
  118.  
  119. #ifndef lint
  120. static char sccsid[] = "@@(#)envelope.c    5.22 (Berkeley) 6/1/90";
  121. #endif /* not lint */
  122.  
  123. #include <sys/types.h>
  124. #include <sys/time.h>
  125. #include <sys/stat.h>
  126. #include <pwd.h>
  127. #include <sys/file.h>
  128. #include "sendmail.h"
  129.  
  130. /*
  131. **  NEWENVELOPE -- allocate a new envelope
  132. **
  133. **    Supports inheritance.
  134. **
  135. **    Parameters:
  136. **        e -- the new envelope to fill in.
  137. **
  138. **    Returns:
  139. **        e.
  140. **
  141. **    Side Effects:
  142. **        none.
  143. */
  144.  
  145. ENVELOPE *
  146. newenvelope(e)
  147.     register ENVELOPE *e;
  148. {
  149.     register ENVELOPE *parent;
  150.     extern putheader(), putbody();
  151.     extern ENVELOPE BlankEnvelope;
  152.  
  153.     parent = CurEnv;
  154.     if (e == CurEnv)
  155.         parent = e->e_parent;
  156.     clearenvelope(e, TRUE);
  157.     if (e == CurEnv)
  158.         bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from);
  159.     else
  160.         bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
  161.     e->e_parent = parent;
  162.     e->e_ctime = curtime();
  163.     e->e_msgpriority = parent->e_msgsize;
  164.     e->e_puthdr = putheader;
  165.     e->e_putbody = putbody;
  166.     if (CurEnv->e_xfp != NULL)
  167.         (void) fflush(CurEnv->e_xfp);
  168.  
  169.     return (e);
  170. }
  171. /*
  172. **  DROPENVELOPE -- deallocate an envelope.
  173. **
  174. **    Parameters:
  175. **        e -- the envelope to deallocate.
  176. **
  177. **    Returns:
  178. **        none.
  179. **
  180. **    Side Effects:
  181. **        housekeeping necessary to dispose of an envelope.
  182. **        Unlocks this queue file.
  183. */
  184.  
  185. dropenvelope(e)
  186.     register ENVELOPE *e;
  187. {
  188.     bool queueit = FALSE;
  189.     register ADDRESS *q;
  190.  
  191.     if (tTd(50, 1))
  192.     {
  193.         printf("dropenvelope %x id=", e);
  194.         xputs(e->e_id);
  195.         printf(" flags=%o\n", e->e_flags);
  196.     }
  197. #ifdef LOG
  198.     if (LogLevel > 10)
  199.         syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
  200.                   e->e_id == NULL ? "(none)" : e->e_id,
  201.                   e->e_flags, getpid());
  202. #endif LOG
  203.  
  204.     /* we must have an id to remove disk files */
  205.     if (e->e_id == NULL)
  206.         return;
  207.  
  208.     /*
  209.     **  Extract state information from dregs of send list.
  210.     */
  211.  
  212.     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  213.     {
  214.         if (bitset(QQUEUEUP, q->q_flags))
  215.             queueit = TRUE;
  216.     }
  217.  
  218.     /*
  219.     **  Send back return receipts as requested.
  220.     */
  221.  
  222.     if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags))
  223.     {
  224.         auto ADDRESS *rlist = NULL;
  225.  
  226.         sendtolist(CurEnv->e_receiptto, (ADDRESS *) NULL, &rlist);
  227.         (void) returntosender("Return receipt", rlist, FALSE);
  228.     }
  229.  
  230.     /*
  231.     **  Arrange to send error messages if there are fatal errors.
  232.     */
  233.  
  234.     if (bitset(EF_FATALERRS|EF_TIMEOUT, e->e_flags) && ErrorMode != EM_QUIET)
  235.         savemail(e);
  236.  
  237.     /*
  238.     **  Instantiate or deinstantiate the queue.
  239.     */
  240.  
  241.     if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) ||
  242.         bitset(EF_CLRQUEUE, e->e_flags))
  243.     {
  244.         if (e->e_df != NULL)
  245.             xunlink(e->e_df);
  246.         xunlink(queuename(e, 'q'));
  247.     }
  248.     else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
  249.     {
  250. #ifdef QUEUE
  251.         FILE *lockfp, *queueup();
  252.         lockfp = queueup(e, FALSE, FALSE);
  253.         if (lockfp != NULL)
  254.             (void) fclose(lockfp);
  255. #else QUEUE
  256.         syserr("dropenvelope: queueup");
  257. #endif QUEUE
  258.     }
  259.  
  260.     /* now unlock the job */
  261.     closexscript(e);
  262.     unlockqueue(e);
  263.  
  264.     /* make sure that this envelope is marked unused */
  265.     e->e_id = e->e_df = NULL;
  266.     if (e->e_dfp != NULL)
  267.         (void) fclose(e->e_dfp);
  268.     e->e_dfp = NULL;
  269. }
  270. /*
  271. **  CLEARENVELOPE -- clear an envelope without unlocking
  272. **
  273. **    This is normally used by a child process to get a clean
  274. **    envelope without disturbing the parent.
  275. **
  276. **    Parameters:
  277. **        e -- the envelope to clear.
  278. **        fullclear - if set, the current envelope is total
  279. **            garbage and should be ignored; otherwise,
  280. **            release any resources it may indicate.
  281. **
  282. **    Returns:
  283. **        none.
  284. **
  285. **    Side Effects:
  286. **        Closes files associated with the envelope.
  287. **        Marks the envelope as unallocated.
  288. */
  289.  
  290. clearenvelope(e, fullclear)
  291.     register ENVELOPE *e;
  292.     bool fullclear;
  293. {
  294.     register HDR *bh;
  295.     register HDR **nhp;
  296.     extern ENVELOPE BlankEnvelope;
  297.  
  298.     if (!fullclear)
  299.     {
  300.         /* clear out any file information */
  301.         if (e->e_xfp != NULL)
  302.             (void) fclose(e->e_xfp);
  303.         if (e->e_dfp != NULL)
  304.             (void) fclose(e->e_dfp);
  305.     }
  306.  
  307.     /* now clear out the data */
  308.     STRUCTCOPY(BlankEnvelope, *e);
  309.     bh = BlankEnvelope.e_header;
  310.     nhp = &e->e_header;
  311.     while (bh != NULL)
  312.     {
  313.         *nhp = (HDR *) xalloc(sizeof *bh);
  314.         bcopy((char *) bh, (char *) *nhp, sizeof *bh);
  315.         bh = bh->h_link;
  316.         nhp = &(*nhp)->h_link;
  317.     }
  318. }
  319. /*
  320. **  INITSYS -- initialize instantiation of system
  321. **
  322. **    In Daemon mode, this is done in the child.
  323. **
  324. **    Parameters:
  325. **        none.
  326. **
  327. **    Returns:
  328. **        none.
  329. **
  330. **    Side Effects:
  331. **        Initializes the system macros, some global variables,
  332. **        etc.  In particular, the current time in various
  333. **        forms is set.
  334. */
  335.  
  336. initsys()
  337. {
  338.     static char cbuf[5];            /* holds hop count */
  339.     static char pbuf[10];            /* holds pid */
  340. #ifdef TTYNAME
  341.     static char ybuf[10];            /* holds tty id */
  342.     register char *p;
  343. #endif TTYNAME
  344.     extern char *ttyname();
  345.     extern char *macvalue();
  346.     extern char Version[];
  347.  
  348.     /*
  349.     **  Give this envelope a reality.
  350.     **    I.e., an id, a transcript, and a creation time.
  351.     */
  352.  
  353.     openxscript(CurEnv);
  354.     CurEnv->e_ctime = curtime();
  355.  
  356.     /*
  357.     **  Set OutChannel to something useful if stdout isn't it.
  358.     **    This arranges that any extra stuff the mailer produces
  359.     **    gets sent back to the user on error (because it is
  360.     **    tucked away in the transcript).
  361.     */
  362.  
  363.     if (OpMode == MD_DAEMON && QueueRun)
  364.         OutChannel = CurEnv->e_xfp;
  365.  
  366.     /*
  367.     **  Set up some basic system macros.
  368.     */
  369.  
  370.     /* process id */
  371.     (void) sprintf(pbuf, "%d", getpid());
  372.     define('p', pbuf, CurEnv);
  373.  
  374.     /* hop count */
  375.     (void) sprintf(cbuf, "%d", CurEnv->e_hopcount);
  376.     define('c', cbuf, CurEnv);
  377.  
  378.     /* time as integer, unix time, arpa time */
  379.     settime();
  380.  
  381. #ifdef TTYNAME
  382.     /* tty name */
  383.     if (macvalue('y', CurEnv) == NULL)
  384.     {
  385.         p = ttyname(2);
  386.         if (p != NULL)
  387.         {
  388.             if (rindex(p, '/') != NULL)
  389.                 p = rindex(p, '/') + 1;
  390.             (void) strcpy(ybuf, p);
  391.             define('y', ybuf, CurEnv);
  392.         }
  393.     }
  394. #endif TTYNAME
  395. }
  396. /*
  397. **  SETTIME -- set the current time.
  398. **
  399. **    Parameters:
  400. **        none.
  401. **
  402. **    Returns:
  403. **        none.
  404. **
  405. **    Side Effects:
  406. **        Sets the various time macros -- $a, $b, $d, $t.
  407. */
  408.  
  409. settime()
  410. {
  411.     register char *p;
  412.     auto time_t now;
  413.     static char tbuf[20];            /* holds "current" time */
  414.     static char dbuf[30];            /* holds ctime(tbuf) */
  415.     register struct tm *tm;
  416.     extern char *arpadate();
  417.     extern struct tm *gmtime();
  418.     extern char *macvalue();
  419.  
  420.     now = curtime();
  421.     tm = gmtime(&now);
  422.     (void) sprintf(tbuf, "%02d%02d%02d%02d%02d", tm->tm_year, tm->tm_mon+1,
  423.             tm->tm_mday, tm->tm_hour, tm->tm_min);
  424.     define('t', tbuf, CurEnv);
  425.     (void) strcpy(dbuf, ctime(&now));
  426.     *index(dbuf, '\n') = '\0';
  427.     if (macvalue('d', CurEnv) == NULL)
  428.         define('d', dbuf, CurEnv);
  429.     p = newstr(arpadate(dbuf));
  430.     if (macvalue('a', CurEnv) == NULL)
  431.         define('a', p, CurEnv);
  432.     define('b', p, CurEnv);
  433. }
  434. /*
  435. **  OPENXSCRIPT -- Open transcript file
  436. **
  437. **    Creates a transcript file for possible eventual mailing or
  438. **    sending back.
  439. **
  440. **    Parameters:
  441. **        e -- the envelope to create the transcript in/for.
  442. **
  443. **    Returns:
  444. **        none
  445. **
  446. **    Side Effects:
  447. **        Creates the transcript file.
  448. */
  449.  
  450. openxscript(e)
  451.     register ENVELOPE *e;
  452. {
  453.     register char *p;
  454.     int fd;
  455.  
  456. # ifdef LOG
  457.     if (LogLevel > 19)
  458.         syslog(LOG_DEBUG, "%s: openx%s", e->e_id, e->e_xfp == NULL ? "" : " (no)");
  459. # endif LOG
  460.     if (e->e_xfp != NULL)
  461.         return;
  462.     p = queuename(e, 'x');
  463.     fd = open(p, O_WRONLY|O_CREAT, 0644);
  464.     if (fd < 0)
  465.         syserr("Can't create %s", p);
  466.     else
  467.         e->e_xfp = fdopen(fd, "w");
  468. }
  469. /*
  470. **  CLOSEXSCRIPT -- close the transcript file.
  471. **
  472. **    Parameters:
  473. **        e -- the envelope containing the transcript to close.
  474. **
  475. **    Returns:
  476. **        none.
  477. **
  478. **    Side Effects:
  479. **        none.
  480. */
  481.  
  482. closexscript(e)
  483.     register ENVELOPE *e;
  484. {
  485.     if (e->e_xfp == NULL)
  486.         return;
  487.     (void) fclose(e->e_xfp);
  488.     e->e_xfp = NULL;
  489. }
  490. /*
  491. **  SETSENDER -- set the person who this message is from
  492. **
  493. **    Under certain circumstances allow the user to say who
  494. **    s/he is (using -f or -r).  These are:
  495. **    1.  The user's uid is zero (root).
  496. **    2.  The user's login name is in an approved list (typically
  497. **        from a network server).
  498. **    3.  The address the user is trying to claim has a
  499. **        "!" character in it (since #2 doesn't do it for
  500. **        us if we are dialing out for UUCP).
  501. **    A better check to replace #3 would be if the
  502. **    effective uid is "UUCP" -- this would require me
  503. **    to rewrite getpwent to "grab" uucp as it went by,
  504. **    make getname more nasty, do another passwd file
  505. **    scan, or compile the UID of "UUCP" into the code,
  506. **    all of which are reprehensible.
  507. **
  508. **    Assuming all of these fail, we figure out something
  509. **    ourselves.
  510. **
  511. **    Parameters:
  512. **        from -- the person we would like to believe this message
  513. **            is from, as specified on the command line.
  514. **
  515. **    Returns:
  516. **        none.
  517. **
  518. **    Side Effects:
  519. **        sets sendmail's notion of who the from person is.
  520. */
  521.  
  522. setsender(from)
  523.     char *from;
  524. {
  525.     register char **pvp;
  526.     char *realname = NULL;
  527.     register struct passwd *pw;
  528.     char buf[MAXNAME];
  529.     char pvpbuf[PSBUFSIZE];
  530.     extern struct passwd *getpwnam();
  531.     extern char *macvalue();
  532.     extern char **prescan();
  533.     extern bool safefile();
  534.     extern char *FullName;
  535.  
  536.     if (tTd(45, 1))
  537.         printf("setsender(%s)\n", from == NULL ? "" : from);
  538.  
  539.     /*
  540.     **  Figure out the real user executing us.
  541.     **    Username can return errno != 0 on non-errors.
  542.     */
  543.  
  544.     if (QueueRun || OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
  545.         realname = from;
  546.     if (realname == NULL || realname[0] == '\0')
  547.     {
  548.         extern char *username();
  549.  
  550.         realname = username();
  551.     }
  552.  
  553.     /*
  554.     **  Determine if this real person is allowed to alias themselves.
  555.     */
  556.  
  557.     if (from != NULL)
  558.     {
  559.         extern bool trusteduser();
  560.  
  561.         if (!trusteduser(realname) && getuid() != geteuid() &&
  562.             index(from, '!') == NULL && getuid() != 0)
  563.         {
  564.             /* network sends -r regardless (why why why?) */
  565.             /* syserr("%s, you cannot use the -f flag", realname); */
  566.             from = NULL;
  567.         }
  568.     }
  569.  
  570.     SuprErrs = TRUE;
  571.     if (from == NULL || parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL)
  572.     {
  573.         /* log garbage addresses for traceback */
  574.         if (from != NULL)
  575.         {
  576. # ifdef LOG
  577.             if (LogLevel >= 1)
  578.                 if (realname == from && RealHostName != NULL)
  579.                 syslog(LOG_NOTICE,
  580.                     "from=%s unparseable, received from %s",
  581.                     from, RealHostName);
  582.                 else
  583.                 syslog(LOG_NOTICE,
  584.                     "Unparseable username %s wants from=%s",
  585.                     realname, from);
  586. # endif LOG
  587.         }
  588.         from = newstr(realname);
  589.         if (parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL &&
  590.             parseaddr("postmaster", &CurEnv->e_from, 1, '\0') == NULL)
  591.         {
  592.             syserr("setsender: can't even parse postmaster!");
  593.         }
  594.     }
  595.     else
  596.         FromFlag = TRUE;
  597.     CurEnv->e_from.q_flags |= QDONTSEND;
  598.     loweraddr(&CurEnv->e_from);
  599.     SuprErrs = FALSE;
  600.  
  601.     if (CurEnv->e_from.q_mailer == LocalMailer &&
  602.         (pw = getpwnam(CurEnv->e_from.q_user)) != NULL)
  603.     {
  604.         /*
  605.         **  Process passwd file entry.
  606.         */
  607.  
  608.  
  609.         /* extract home directory */
  610.         CurEnv->e_from.q_home = newstr(pw->pw_dir);
  611.         define('z', CurEnv->e_from.q_home, CurEnv);
  612.  
  613.         /* extract user and group id */
  614.         CurEnv->e_from.q_uid = pw->pw_uid;
  615.         CurEnv->e_from.q_gid = pw->pw_gid;
  616.  
  617.         /* if the user has given fullname already, don't redefine */
  618.         if (FullName == NULL)
  619.             FullName = macvalue('x', CurEnv);
  620.         if (FullName != NULL && FullName[0] == '\0')
  621.             FullName = NULL;
  622.  
  623.         /* extract full name from passwd file */
  624.         if (FullName == NULL && pw->pw_gecos != NULL &&
  625.             strcmp(pw->pw_name, CurEnv->e_from.q_user) == 0)
  626.         {
  627.             buildfname(pw->pw_gecos, CurEnv->e_from.q_user, buf);
  628.             if (buf[0] != '\0')
  629.                 FullName = newstr(buf);
  630.         }
  631.         if (FullName != NULL)
  632.             define('x', FullName, CurEnv);
  633.     }
  634.     else
  635.     {
  636.         if (CurEnv->e_from.q_home == NULL)
  637.             CurEnv->e_from.q_home = getenv("HOME");
  638.         CurEnv->e_from.q_uid = getuid();
  639.         CurEnv->e_from.q_gid = getgid();
  640.     }
  641.  
  642.     /*
  643.     **  Rewrite the from person to dispose of possible implicit
  644.     **    links in the net.
  645.     */
  646.  
  647.     pvp = prescan(from, '\0', pvpbuf);
  648.     if (pvp == NULL)
  649.     {
  650. # ifdef LOG
  651.         if (LogLevel >= 1)
  652.             syslog(LOG_NOTICE, "cannot prescan from (%s)", from);
  653. # endif
  654.         usrerr("cannot prescan from (%s)", from);
  655.         finis();
  656.     }
  657.     rewrite(pvp, 3);
  658.     rewrite(pvp, 1);
  659.     rewrite(pvp, 4);
  660.     cataddr(pvp, buf, sizeof buf);
  661.     define('f', newstr(buf), CurEnv);
  662.  
  663.     /* save the domain spec if this mailer wants it */
  664.     if (CurEnv->e_from.q_mailer != NULL &&
  665.         bitnset(M_CANONICAL, CurEnv->e_from.q_mailer->m_flags))
  666.     {
  667.         extern char **copyplist();
  668.  
  669.         while (*pvp != NULL && strcmp(*pvp, "@@") != 0)
  670.             pvp++;
  671.         if (*pvp != NULL)
  672.             CurEnv->e_fromdomain = copyplist(pvp, TRUE);
  673.     }
  674. }
  675. /*
  676. **  TRUSTEDUSER -- tell us if this user is to be trusted.
  677. **
  678. **    Parameters:
  679. **        user -- the user to be checked.
  680. **
  681. **    Returns:
  682. **        TRUE if the user is in an approved list.
  683. **        FALSE otherwise.
  684. **
  685. **    Side Effects:
  686. **        none.
  687. */
  688.  
  689. bool
  690. trusteduser(user)
  691.     char *user;
  692. {
  693.     register char **ulist;
  694.     extern char *TrustedUsers[];
  695.  
  696.     for (ulist = TrustedUsers; *ulist != NULL; ulist++)
  697.         if (strcmp(*ulist, user) == 0)
  698.             return (TRUE);
  699.     return (FALSE);
  700. }
  701. @
  702.  
  703.  
  704. 5.22.0.1
  705. log
  706. @Date: Wed, 20 Jun 90 15:39:37 -0400 (EDT)
  707. From: Craig_Everhart@@transarc.com
  708. To: paul@@uxc.cso.uiuc.edu (Paul Pomes - UofIllinois CSO)
  709. Subject: Re: Sendmail V5.64 + IDA enhancements available for anon-FTP
  710.  
  711. Here's a sendmail patch for you that I've been sending around.  I've
  712. been running it for years, and it was only when Peter Neumann had such
  713. trouble with RISKS duplications that I decided to try to propagate it.
  714.  
  715. The problem addressed by the fix is that if sendmail delivers to a long
  716. address list (in a single request) but crashes in the middle, it has no
  717. record of the successful deliveries that it has made so far, so when it
  718. eventually gets around to retrying that request, it re-delivers to all
  719. the addresses to which it had been able to deliver earlier.  Not only
  720. does this generate duplicate mail, but the re-delivery process also
  721. requires additional queue processing time, so that it might continue to
  722. take a long time even to attempt delivery to the last address in the
  723. list.
  724.  
  725. The solution that this patch builds is simple and not very expensive:
  726. after every successful mail delivery, the qf* file is rewritten,
  727. omitting the recipient to whom delivery was successful.  The qf* file
  728. gets shorter even as the request is processed.  A crash in the middle of
  729. processing the list will result in duplicate delivery to at most one
  730. host.  It doesn't require that much time to rewrite the qf* file;
  731. certainly less time than the delivery itself takes.
  732.  
  733. The only real disadvantage I can imagine is that my sendmail sources
  734. have diverged in many ways from a UCB version of about 1986. 
  735. Nonetheless, it shouldn't be difficult to install this change.
  736.  
  737. As you can see, this change works by adding an additional flag parameter
  738. to queueup(), then calling queueup() (from sendall()) with this
  739. parameter set sometimes.  The queueup() flag parameter controls which
  740. addresses are rewritten, looking at different flags.
  741.  
  742. So here's the patch.  I hope that you find it useful.  I look forward to
  743. your reply.
  744.  
  745.         Thanks,
  746.         Craig Everhart
  747. @
  748. text
  749. @d154 1
  750. a154 1
  751.         lockfp = queueup(e, FALSE, FALSE, FALSE);
  752. @
  753.  
  754.  
  755. 5.22.0.2
  756. log
  757. @Dropped re-write of queue file due to bug w. too many open files.  This
  758. feature isn't too important for us.
  759. @
  760. text
  761. @d154 1
  762. a154 1
  763.         lockfp = queueup(e, FALSE, FALSE);
  764. @
  765.  
  766.  
  767. 5.22.0.3
  768. log
  769. @AIX, unlike the rest of the world, does not include time.h with sys/time.h.
  770. @
  771. text
  772. @a26 3
  773. #ifdef _IBMESA
  774. # include <time.h>
  775. #endif /* _IBMESA brain-damage */
  776. @
  777.  
  778.  
  779. 5.22.0.4
  780. log
  781. @Changed _IBMESA to _AIX (provided in /etc/xlc.cfg).  <sys/file.h> now
  782. included in sendmail.h.
  783. @
  784. text
  785. @d27 1
  786. a27 1
  787. #ifdef _AIX
  788. d29 1
  789. a29 1
  790. #endif /* _AIX brain-damage */
  791. d32 1
  792. @
  793.  
  794.  
  795. 5.22.0.5
  796. log
  797. @Changed calls to parseaddr() to not pass constant strings.  Commented
  798. out tokens following #else and #endif statements.
  799. @
  800. text
  801. @d106 1
  802. a106 1
  803. #endif /* LOG */
  804. d159 1
  805. a159 1
  806. #else /* !QUEUE */
  807. d161 1
  808. a161 1
  809. #endif /* QUEUE */
  810. d247 1
  811. a247 1
  812. #endif /* TTYNAME */
  813. d298 1
  814. a298 1
  815. #endif /* TTYNAME */
  816. d360 1
  817. a360 1
  818. #ifdef LOG
  819. d363 1
  820. a363 1
  821. #endif /* LOG */
  822. a425 2
  823. static char PostMaster[] = "postmaster";    /* for gcc */
  824.  
  825. d480 1
  826. a480 1
  827. #ifdef LOG
  828. d490 1
  829. a490 1
  830. #endif /* LOG */
  831. d494 1
  832. a494 1
  833.             parseaddr(PostMaster, &CurEnv->e_from, 1, '\0') == NULL)
  834. d554 1
  835. a554 1
  836. #ifdef LOG
  837. d557 1
  838. a557 1
  839. #endif /* LOG */
  840. @
  841.  
  842.  
  843. 5.22.0.6
  844. log
  845. @Deleted #include <sys/types.h> as it's already included via sendmail.h from
  846. useful.h.  #include "sendmail.h" relocated to top of #include list.
  847. @
  848. text
  849. @d25 1
  850. a25 1
  851. #include "sendmail.h"
  852. d32 1
  853. @
  854.  
  855.  
  856. 5.22.0.7
  857. log
  858. @Added static keyword to declarations for closexscript() and trusteduser().
  859. @
  860. text
  861. @a92 1
  862.     static void closexscript();
  863. a384 1
  864. static void
  865. d464 1
  866. a464 1
  867.         static bool trusteduser();
  868. d594 1
  869. a594 1
  870. static bool
  871. @
  872.  
  873.  
  874. 5.22.0.8
  875. log
  876. @ANSIfied.
  877. @
  878. text
  879. @a32 8
  880. #ifdef __STDC__
  881. static void closexscript(ENVELOPE *);
  882. static bool trusteduser(const char *);
  883. #else /* !__STDC__ */
  884. static void closexscript();
  885. static bool trusteduser();
  886. #endif /* __STDC__ */
  887.  
  888. d53 1
  889. a87 1
  890. void
  891. d93 1
  892. d155 1
  893. a155 2
  894.         FILE *lockfp;
  895.  
  896. a193 1
  897. void
  898. a239 1
  899. void
  900. d249 1
  901. a312 1
  902. void
  903. d320 3
  904. a353 1
  905. void
  906. a428 1
  907. void
  908. d437 4
  909. d454 3
  910. d458 1
  911. d466 2
  912. d574 2
  913. d598 1
  914. a598 1
  915.     const char *user;
  916. @
  917.  
  918.  
  919. 5.22.0.9
  920. log
  921. @Added RCS ID string
  922. @
  923. text
  924. @a22 1
  925. static char  rcsid[] = "@@(#)$Id$";
  926. @
  927.  
  928.  
  929. 5.22.0.10
  930. log
  931. @System 5 and general improvement patches contributed by Bruce Lilly
  932. (bruce%balilly@@broadcast.sony.com).
  933. @
  934. text
  935. @d22 2
  936. a23 2
  937. static char sccsid[] = "@@(#)envelope.c    5.22 (Berkeley) 6/1/90    %I% local";
  938. static char  rcsid[] = "@@(#)$Id: envelope.c,v 5.22.0.9 1991/04/05 14:55:15 paul Exp paul $";
  939. d62 1
  940. d259 2
  941. @
  942.  
  943.  
  944. 5.22.0.11
  945. log
  946. @Moved #include of time.h to sendmail.h.
  947. @
  948. text
  949. @d23 1
  950. a23 1
  951. static char  rcsid[] = "@@(#)$Id: envelope.c,v 5.22.0.10 1991/05/18 17:27:51 paul Exp paul $";
  952. d27 4
  953. @
  954.  
  955.  
  956. 5.22.0.12
  957. log
  958. @Use 4 digit years.
  959. @
  960. text
  961. @d23 1
  962. a23 1
  963. static char  rcsid[] = "@@(#)$Id: envelope.c,v 5.22.0.11 1991/05/23 21:32:01 paul Exp paul $";
  964. d321 2
  965. a322 2
  966.     static char tbuf[13];            /* holds "current" time */
  967.     static char dbuf[26];            /* holds ctime(tbuf) */
  968. d327 2
  969. a328 2
  970.     (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", 1900 + tm->tm_year,
  971.         tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
  972. @
  973.  
  974.  
  975. 5.22.0.13
  976. log
  977. @From: e07@@nikhefh.nikhef.nl (Eric Wassenaar)
  978. Newsgroups: comp.mail.sendmail
  979. Subject: sendmail may fetch values from wrong envelope
  980. Date: 6 Jun 91 13:25:26 GMT
  981. Organization: Nikhef-H, Amsterdam (the Netherlands).
  982.  
  983. To those who care about details:
  984. In the following cases values may be fetched from the wrong
  985. envelope, if the specified 'e' is not the same as 'CurEnv'.
  986. @
  987. text
  988. @d23 1
  989. a23 1
  990. static char  rcsid[] = "@@(#)$Id: envelope.c,v 5.22.0.12 1991/05/29 19:43:33 paul Exp paul $";
  991. d133 1
  992. a133 1
  993.         sendtolist(e->e_receiptto, (ADDRESS *) NULL, &rlist);
  994. @
  995.  
  996.  
  997. 5.22.0.14
  998. log
  999. @sccsid string changed.
  1000. @
  1001. text
  1002. @d22 2
  1003. a23 2
  1004. static char sccsid[] = "@@(#)envelope.c    5.22 (Berkeley) 6/1/90";
  1005. static char  rcsid[] = "@@(#)$Id: envelope.c,v 5.22.0.13 1991/06/07 20:15:06 paul Exp paul $";
  1006. @
  1007.